ডেটাবেসের Concurrency Control এর জন্য Optimistic Locking এবং Pessimistic Locking ব্যবহৃত হয়। Spring ORM এ এগুলো Hibernate এবং JPA এর মাধ্যমে ইমপ্লিমেন্ট করা যায়। এই লকিং মেকানিজম নিশ্চিত করে যে ডেটা একাধিক থ্রেড বা ট্রানজ্যাকশন দ্বারা একসঙ্গে পরিবর্তিত হলে ডেটা সঠিক থাকে।
Optimistic Locking
Optimistic Locking ধরে নেয় যে ডেটার অ্যাক্সেসের সময় কনফ্লিক্টের সম্ভাবনা কম। এটি ডেটার পরিবর্তনের সময় যাচাই করে কোনো কনফ্লিক্ট হয়েছে কিনা।
কীভাবে কাজ করে?
- ডাটাবেস টেবিলে একটি Version Column যোগ করা হয়।
- ডেটা আপডেট করার সময় Version Number চেক করা হয়।
- যদি Version Number মিলে না যায়, তাহলে OptimisticLockException ছুড়ে দেয়।
উদাহরণ: Spring ORM-এ Optimistic Locking
Entity ক্লাসে Version ফিল্ড যোগ করা
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Version;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
@Version
private int version;
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
Optimistic Locking এর ব্যবহার
import jakarta.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateProductPrice(Long productId, Double newPrice) {
Product product = productRepository.findById(productId).orElseThrow();
product.setPrice(newPrice);
productRepository.save(product);
}
}
Pessimistic Locking
Pessimistic Locking ধরে নেয় যে ডেটার অ্যাক্সেসের সময় কনফ্লিক্ট হওয়ার সম্ভাবনা বেশি। এটি ডেটার অ্যাক্সেসের সময় সরাসরি Lock প্রয়োগ করে।
কীভাবে কাজ করে?
- ট্রানজ্যাকশন শুরু করার সময়ই ডেটা Read বা Write করার জন্য লক আরোপ করা হয়।
- এটি নিশ্চিত করে যে অন্য কোনো ট্রানজ্যাকশন একই ডেটা একসঙ্গে অ্যাক্সেস করতে পারবে না।
উদাহরণ: Spring ORM-এ Pessimistic Locking
Pessimistic Lock ব্যবহার
import jakarta.persistence.LockModeType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import jakarta.transaction.Transactional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateProductPriceWithLock(Long productId, Double newPrice) {
Product product = productRepository.findByIdWithLock(productId);
product.setPrice(newPrice);
productRepository.save(product);
}
}
Custom Query সহ Pessimistic Lock
import jakarta.persistence.LockModeType;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.data.jpa.repository.Query;
public interface ProductRepository extends JpaRepository<Product, Long> {
@Lock(LockModeType.PESSIMISTIC_WRITE)
@Query("SELECT p FROM Product p WHERE p.id = :id")
Product findByIdWithLock(Long id);
}
Optimistic vs Pessimistic Locking
| বৈশিষ্ট্য | Optimistic Locking | Pessimistic Locking |
|---|---|---|
| কনফ্লিক্টের সম্ভাবনা | কম (Low) | বেশি (High) |
| লকিং টাইপ | ভার্চুয়াল (Version Number দিয়ে) | সরাসরি ডেটার উপর Lock আরোপ |
| পারফরম্যান্স | তুলনামূলকভাবে ভালো | ধীর (লক আরোপ করার কারণে) |
| ব্যবহারিক উদাহরণ | Read-heavy অ্যাপ্লিকেশন | Write-heavy বা ট্রানজ্যাকশন-ইনটেনসিভ সিস্টেম |
উপসংহার
Optimistic Locking এবং Pessimistic Locking Spring ORM-এConcurrency Management নিশ্চিত করতে ব্যবহৃত হয়। Optimistic Locking সাধারণত read-heavy অ্যাপ্লিকেশনগুলোর জন্য কার্যকর এবং Pessimistic Locking write-heavy সিস্টেমে ব্যবহৃত হয়। সঠিক পরিস্থিতিতে সঠিক মেথড ব্যবহার করা ডেটার নির্ভুলতা ও পারফরম্যান্স নিশ্চিত করে।
Locking ডাটাবেসের এমন একটি প্রক্রিয়া যা একাধিক ব্যবহারকারী বা প্রসেস যখন একই ডেটা অ্যাক্সেস বা পরিবর্তন করার চেষ্টা করে, তখন ডেটার সঠিকতা এবং সামঞ্জস্য নিশ্চিত করে। এটি বিশেষত Concurrency Control এর জন্য ব্যবহৃত হয়, যেখানে একই ডেটার উপর একাধিক অপারেশন পারফর্ম করা হয়।
Locking এর প্রকারভেদ
Hibernate এবং JPA-তে Locking প্রধানত দুই প্রকার:
১. Optimistic Locking
Optimistic Locking ধরে নেয় যে ডেটার উপর কনফ্লিক্ট খুব কম হয়। এটি কোনো লক নেয় না; বরং একটি Version বা Timestamp ফিল্ড ব্যবহার করে ডেটার সামঞ্জস্যতা যাচাই করে।
কাজের পদ্ধতি:
- যখন একটি রেকর্ড রিড করা হয়, তখন সেই রেকর্ডের একটি ভার্সন নম্বর বা টাইমস্ট্যাম্পও রিড করা হয়।
- আপডেট করার সময় Hibernate চেক করে যে ভার্সন নম্বর বা টাইমস্ট্যাম্প অপরিবর্তিত আছে কি না।
- যদি অন্য কোনো ট্রানজেকশন ডেটা আপডেট করে থাকে, তাহলে OptimisticLockException থ্রো করে।
উদাহরণ:
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Version
private int version;
// Getters and Setters
}
২. Pessimistic Locking
Pessimistic Locking ধরে নেয় যে ডেটার উপর কনফ্লিক্ট হতে পারে এবং ডেটা রিড বা রাইট করার সময় তা লক করে রাখে।
কাজের পদ্ধতি:
- যখন একটি রেকর্ড রিড বা আপডেট করা হয়, তখন সেই রেকর্ডকে লক করা হয়।
- অন্য কোনো প্রসেস লক থাকা অবস্থায় সেই রেকর্ড অ্যাক্সেস করতে পারে না।
- এটি সাধারণত Shared Lock (রিডের জন্য) এবং Exclusive Lock (রাইটের জন্য) হিসেবে কাজ করে।
উদাহরণ:
// Pessimistic Read Lock
entityManager.lock(product, LockModeType.PESSIMISTIC_READ);
// Pessimistic Write Lock
entityManager.lock(product, LockModeType.PESSIMISTIC_WRITE);
Locking এর প্রয়োজনীয়তা
১. ডেটার সামঞ্জস্যতা নিশ্চিত করা
Locking নিশ্চিত করে যে একই ডেটা একাধিক ট্রানজেকশন দ্বারা পরিবর্তিত হলে ডেটা ইনকনসিস্টেন্সি না হয়।
২. ডেটা রেস (Data Race) এড়ানো
Concurrency এর কারণে ডেটা রেস (যখন একাধিক প্রসেস ডেটা অ্যাক্সেস করে) হতে পারে। Locking এই সমস্যাগুলো প্রতিরোধ করে।
৩. ডেটার অখণ্ডতা বজায় রাখা (Data Integrity)
Locking নিশ্চিত করে যে কোনো একটি ট্রানজেকশন শেষ না হওয়া পর্যন্ত অন্য ট্রানজেকশন সেই ডেটা পরিবর্তন করতে পারবে না।
৪. Concurrency সমস্যা সমাধান করা
Locking ব্যবহার করে Dirty Read, Non-repeatable Read, এবং Phantom Read এর মতো সমস্যা প্রতিরোধ করা যায়।
Optimistic এবং Pessimistic Locking এর তুলনা
| বৈশিষ্ট্য | Optimistic Locking | Pessimistic Locking |
|---|---|---|
| লক প্রক্রিয়া | কোনো লক নেয় না, ভার্সন বা টাইমস্ট্যাম্প ব্যবহার করে | ডেটার উপর সরাসরি লক প্রয়োগ করে |
| কনফ্লিক্টের সম্ভাবনা | কম কনফ্লিক্ট থাকলে কার্যকর | বেশি কনফ্লিক্ট থাকলে কার্যকর |
| কর্মক্ষমতা (Performance) | ভালো, কারণ লক ব্যবস্থাপনা প্রয়োজন নেই | বেশি রিসোর্স ব্যবহার করে |
| ব্যবহারের ক্ষেত্র | বেশি রিড অপারেশন এবং কম কনফ্লিক্ট | বেশি রাইট অপারেশন এবং বেশি কনফ্লিক্ট |
উদাহরণ প্রকল্প: Locking এর ব্যবহার
১. Entity তৈরি করা (Optimistic Locking সহ)
@Entity
public class Account {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private double balance;
@Version
private int version;
// Getters and Setters
}
২. Pessimistic Locking এর জন্য API
@Transactional
public Account withdrawAmount(Long accountId, double amount) {
Account account = entityManager.find(Account.class, accountId, LockModeType.PESSIMISTIC_WRITE);
if (account.getBalance() >= amount) {
account.setBalance(account.getBalance() - amount);
} else {
throw new InsufficientBalanceException("Insufficient balance.");
}
return account;
}
৩. Optimistic Locking Exception হ্যান্ডেল করা
@Transactional
public Account updateAccount(Account updatedAccount) {
try {
return accountRepository.save(updatedAccount);
} catch (OptimisticLockingFailureException e) {
throw new ConcurrentModificationException("The account was updated by another transaction.");
}
}
সারাংশ
Locking একটি অপরিহার্য প্রক্রিয়া যা ডেটাবেস ট্রানজেকশন এবং কনকারেন্সি সমস্যাগুলো সমাধান করতে সাহায্য করে। Optimistic Locking এবং Pessimistic Locking এর মধ্যে পার্থক্য বুঝে প্রয়োজন অনুযায়ী ব্যবহার করলে ডেটার অখণ্ডতা এবং সামঞ্জস্যতা বজায় রাখা সহজ হয়।
Spring ORM-এ Optimistic Locking এবং Pessimistic Locking হল কনকারেন্সি কন্ট্রোল মেকানিজম, যা ডাটাবেস অ্যাক্সেস করার সময় ডেটার সঠিকতা নিশ্চিত করে। ডেটা পরিবর্তনের সময় মাল্টিপল ট্রানজ্যাকশনের মধ্যে সংঘর্ষ এড়ানোর জন্য এগুলো ব্যবহৃত হয়।
Optimistic Locking
Optimistic Locking হল এমন একটি পদ্ধতি যেখানে ধরে নেওয়া হয়, একই ডেটা একই সময়ে অন্য কেউ আপডেট করবে না। এটি ডেটা আপডেটের আগে চেক করে, ডেটা পরিবর্তিত হয়েছে কিনা।
কিভাবে কাজ করে:
- ডেটার প্রতিটি রেকর্ডে একটি Version বা Timestamp কলাম থাকে।
- যখন কোনো ট্রানজ্যাকশন ডেটা আপডেট করতে চায়, তখন এটি সেই রেকর্ডের বর্তমান Version যাচাই করে।
- যদি Version পরিবর্তিত না হয়, তবে আপডেট সফল হয়; অন্যথায় একটি কনকারেন্সি সমস্যা বলে গণ্য হয় এবং ব্যর্থ হয়।
বৈশিষ্ট্য:
- Deadlock এড়ায়।
- লক ব্যবহৃত হয় না।
- বেশি পড়া-লেখার অ্যাক্সেস (Read-Write Access) ক্ষেত্রে কার্যকর।
উদাহরণ:
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Double price;
@Version
private int version;
// Getters and Setters
}
কার্যপ্রণালী:
versionফিল্ডটি Hibernate দ্বারা স্বয়ংক্রিয়ভাবে পরিচালিত হয়।- ডেটা আপডেটের সময় Hibernate বর্তমান
versionযাচাই করে। - যদি
versionমিলে না যায়, তখন OptimisticLockException নিক্ষেপ করা হয়।
Pessimistic Locking
Pessimistic Locking এমন একটি পদ্ধতি যেখানে ধরে নেওয়া হয়, একই ডেটা অন্য কেউ একসাথে আপডেট করতে পারে। এটি প্রতিরোধ করার জন্য, ডেটা পড়ার বা লেখার সময় লক প্রয়োগ করা হয়।
কিভাবে কাজ করে:
- একটি রেকর্ড অ্যাক্সেস করার সময় Hibernate ডাটাবেসে লক সেট করে।
- অন্য কোনো ট্রানজ্যাকশন সেই রেকর্ড অ্যাক্সেস করতে পারবে না যতক্ষণ লক রিলিজ না হয়।
বৈশিষ্ট্য:
- Deadlock এর সম্ভাবনা থাকে।
- বেশি লেখার অ্যাক্সেস (Write Access) ক্ষেত্রে কার্যকর।
- অন্যান্য ট্রানজ্যাকশনকে ব্লক করে রাখে।
উদাহরণ:
public Product findWithPessimisticLock(Long id) {
return entityManager.find(Product.class, id, LockModeType.PESSIMISTIC_WRITE);
}
LockModeType এর ধরন:
PESSIMISTIC_READ: রিড অপারেশন লক করে, তবে ডেটা পরিবর্তন করতে দেয় না।PESSIMISTIC_WRITE: রাইট অপারেশন লক করে, অন্য ট্রানজ্যাকশনকে সম্পূর্ণ ব্লক করে।PESSIMISTIC_FORCE_INCREMENT: রাইটের সাথে সাথেversionইনক্রিমেন্ট করে।
Optimistic এবং Pessimistic Locking এর পার্থক্য
| প্যারামিটার | Optimistic Locking | Pessimistic Locking |
|---|---|---|
| লকিং কৌশল | লক প্রয়োগ করা হয় না। | লক প্রয়োগ করা হয়। |
| কনফ্লিক্ট সমাধান | Version বা Timestamp দিয়ে সংঘর্ষ নির্ধারণ। | ট্রানজ্যাকশন লক দিয়ে সংঘর্ষ প্রতিরোধ। |
| Deadlock এর ঝুঁকি | Deadlock এর কোনো ঝুঁকি নেই। | Deadlock এর ঝুঁকি রয়েছে। |
| পারফরম্যান্স | বেশি পড়া-লেখা কার্যক্রমে ভালো পারফরম্যান্স। | বেশি লেখার কার্যক্রমে কার্যকর। |
| ব্যবহারিক ক্ষেত্র | কম কনকারেন্ট রাইট অপারেশনের জন্য উপযুক্ত। | বেশি কনকারেন্ট রাইট অপারেশনের জন্য উপযুক্ত। |
| ব্যবহার | @Version ব্যবহার করে সহজে কনফিগার করা যায়। | LockModeType ব্যবহার করে কনফিগার করতে হয়। |
ব্যবহারিক উদাহরণ
Optimistic Locking ব্যর্থতার হ্যান্ডলিং:
try {
product.setPrice(500.0);
productRepository.save(product);
} catch (OptimisticLockException e) {
System.out.println("Concurrency conflict detected!");
}
Pessimistic Locking উদাহরণ:
@Transactional
public Product updateProduct(Long id, double newPrice) {
Product product = entityManager.find(Product.class, id, LockModeType.PESSIMISTIC_WRITE);
product.setPrice(newPrice);
return product;
}
কবে কোনটি ব্যবহার করবেন?
- Optimistic Locking:
- যখন ডেটা পরিবর্তনের সম্ভাবনা কম।
- বড় অ্যাপ্লিকেশন যেখানে বেশি পড়া (Read-Heavy) কাজ হয়।
- Deadlock প্রতিরোধ করতে।
- Pessimistic Locking:
- যখন ডেটা পরিবর্তনের সম্ভাবনা বেশি।
- ছোট অ্যাপ্লিকেশন যেখানে বেশি লেখা (Write-Heavy) কাজ হয়।
- ডেটা সঠিকতা অত্যন্ত গুরুত্বপূর্ণ হলে।
Spring ORM এ Locking মেকানিজম সঠিকভাবে ব্যবহার করলে ডেটা ইন্টেগ্রিটি নিশ্চিত করা যায় এবং অ্যাপ্লিকেশনের কনকারেন্সি সমস্যা এড়ানো সম্ভব হয়।
Spring ORM এবং Hibernate ব্যবহার করে ডাটাবেসের কনকারেন্সি (concurrency) ম্যানেজ করতে @Version অ্যানোটেশন একটি কার্যকরী উপায়। এটি Optimistic Locking বাস্তবায়নে ব্যবহৃত হয়, যা ডাটাবেসে মাল্টিপল ট্রানজ্যাকশনের সময় ডেটা কনসিস্টেন্সি বজায় রাখে।
Optimistic Locking এর ধারণা
Optimistic Locking একটি কৌশল যেখানে ডেটা রিড করার সময় ধরে নেওয়া হয় যে ডেটা অন্য কেউ পরিবর্তন করবে না। তবে, আপডেট করার সময় চেক করা হয় ডেটার সংস্করণ (version) পরিবর্তন হয়েছে কি না। যদি পরিবর্তন হয়ে থাকে, তাহলে কনফ্লিক্ট (conflict) ম্যানেজ করতে উপযুক্ত পদক্ষেপ নেওয়া হয়।
@Version Annotation এর ভূমিকা
- Hibernate বা JPA-তে @Version ব্যবহার করে একটি টেবিলের নির্দিষ্ট কলামকে সংস্করণ (version) ট্র্যাক করার জন্য ব্যবহার করা হয়।
- যখনই কোনও ডেটা আপডেট করা হয়, তখন এই সংস্করণ ফিল্ডটি স্বয়ংক্রিয়ভাবে ইনক্রিমেন্ট হয়।
- ডেটার সংস্করণ চেক করার মাধ্যমে ডেটা কনসিস্টেন্সি নিশ্চিত করা হয়।
@Version ব্যবহার করার পদ্ধতি
1. Entity Class এ @Version যোগ করা
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Version;
@Entity
public class Product {
@Id
private int id;
private String name;
private double price;
@Version
private int version;
// Getter এবং Setter
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getVersion() {
return version;
}
public void setVersion(int version) {
this.version = version;
}
}
2. ডাটাবেসে @Version এর জন্য কলাম সংযোজন
টেবিলের জন্য একটি version বা অনুরূপ কলাম যুক্ত করুন। উদাহরণস্বরূপ:
ALTER TABLE Product ADD version INT DEFAULT 0;
Hibernate স্বয়ংক্রিয়ভাবে এই কলামের মান পরিচালনা করবে।
কাজের পদ্ধতি
- যখন Hibernate বা JPA একটি Entity আপডেট করে, তখন এটি Entity-র বর্তমান সংস্করণ চেক করে।
- যদি সংস্করণটি আগের মানের সঙ্গে মেলে, তাহলে আপডেট সফল হয় এবং সংস্করণ ইনক্রিমেন্ট করা হয়।
- যদি সংস্করণ মেলে না (কারণ অন্য কোনো ট্রানজ্যাকশন ইতিমধ্যে আপডেট করেছে), তাহলে OptimisticLockException থ্রো করা হয়।
উদাহরণ: Optimistic Locking এর বাস্তবায়ন
ডেটা আপডেট
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
public class ProductService {
private EntityManagerFactory emf;
public ProductService() {
emf = Persistence.createEntityManagerFactory("example-unit");
}
public void updateProductPrice(int productId, double newPrice) {
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
Product product = em.find(Product.class, productId);
product.setPrice(newPrice);
em.getTransaction().commit();
} catch (Exception e) {
em.getTransaction().rollback();
e.printStackTrace();
} finally {
em.close();
}
}
}
কনফ্লিক্ট ম্যানেজমেন্ট
যদি একই ডেটা দুইটি ট্রানজ্যাকশন দ্বারা আপডেট করা হয়, তাহলে একটি OptimisticLockException থ্রো হবে, যা নিচের মতো হ্যান্ডেল করা যেতে পারে:
try {
updateProductPrice(1, 150.0);
} catch (OptimisticLockException e) {
System.out.println("Concurrency issue detected! Please retry.");
}
সুবিধা
- ডেটা কনসিস্টেন্সি: একই ডেটা একাধিক ট্রানজ্যাকশনে কনফ্লিক্ট হওয়ার ঝুঁকি কমায়।
- লো রিসোর্স ওভারহেড: Optimistic Locking অতিরিক্ত লক রাখে না, ফলে এটি হালকা ওজনের।
- ব্যবহারের সরলতা: @Version অ্যানোটেশন ব্যবহার করে সহজেই কনফিগার করা যায়।
সীমাবদ্ধতা
- High Contention: যদি ডেটা খুব ঘন ঘন আপডেট হয়, তাহলে কনফ্লিক্টের সম্ভাবনা বেড়ে যায়।
- Rollback প্রয়োজন: কনফ্লিক্টের ক্ষেত্রে ট্রানজ্যাকশন রোলব্যাক করতে হতে পারে।
- ডেটা লস ঝুঁকি: কনফ্লিক্ট ম্যানেজমেন্ট সঠিকভাবে না করা হলে ডেটা লস হতে পারে।
Spring ORM-এ @Version অ্যানোটেশনের মাধ্যমে Optimistic Locking ব্যবহার করে মাল্টিপল ট্রানজ্যাকশন পরিচালনার সময় ডেটার অখণ্ডতা নিশ্চিত করা যায়। এটি একটি কার্যকর এবং ব্যবহার-বান্ধব কৌশল যা Spring ORM বা Hibernate-এর পারফরম্যান্স ও নির্ভরযোগ্যতা বৃদ্ধি করে।
Spring ORM এ Locking ব্যবহার করা হয় কনকারেন্সি কন্ট্রোলের জন্য, যাতে একই ডেটার উপর একাধিক ট্রানজ্যাকশন সঠিকভাবে পরিচালনা করা যায়। Hibernate বা JPA-তে Locking মেকানিজম ডেটাবেস লেভেলে ডেটার কনসিস্টেন্সি নিশ্চিত করে।
Hibernate দুটি ধরনের লকিং সরবরাহ করে:
- Optimistic Locking
- Pessimistic Locking
Optimistic Locking
Optimistic Locking তখন ব্যবহৃত হয় যখন ডেটার সংঘর্ষ (conflict) খুব কম হয়। এটি ডেটা আপডেট করার আগে একটি ভার্সন চেক করে সংঘর্ষ প্রতিরোধ করে।
কনফিগারেশন: Optimistic Locking
Entity-তে @Version ব্যবহার
import jakarta.persistence.*;
@Entity
@Table(name = "products")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "price")
private Double price;
@Version
private Integer version; // Version field for Optimistic Locking
// Getters and Setters
}
ব্যাখ্যা:
@Versionঅ্যানোটেশনটি Hibernate বা JPA-কে বলে দেয়, ট্রানজ্যাকশন চলাকালে ডেটার একটি ভার্সন ট্যাক করুন।- যখন অন্য কেউ একই ডেটা পরিবর্তন করার চেষ্টা করে এবং ভার্সন মেলে না, তখন
OptimisticLockExceptionথ্রো করা হয়।
উদাহরণ: Optimistic Locking
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public Product updateProductPrice(Long id, Double newPrice) {
Product product = productRepository.findById(id).orElseThrow(() -> new RuntimeException("Product not found"));
product.setPrice(newPrice);
return productRepository.save(product);
}
}
Exception Handling:
try {
productService.updateProductPrice(1L, 200.0);
} catch (OptimisticLockException e) {
System.out.println("Conflict detected: " + e.getMessage());
}
Pessimistic Locking
Pessimistic Locking তখন ব্যবহৃত হয় যখন ডেটার সংঘর্ষের সম্ভাবনা বেশি থাকে। এটি ডেটাবেস লেভেলে লক তৈরি করে, যাতে অন্য ট্রানজ্যাকশন সেই ডেটা অ্যাক্সেস করতে না পারে যতক্ষণ না বর্তমান ট্রানজ্যাকশন সম্পূর্ণ হয়।
কনফিগারেশন: Pessimistic Locking
JPA Locking API ব্যবহার
import jakarta.persistence.*;
import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository
public class ProductRepository {
@PersistenceContext
private EntityManager entityManager;
public Optional<Product> findProductWithPessimisticLock(Long id) {
return Optional.ofNullable(entityManager.find(Product.class, id, LockModeType.PESSIMISTIC_WRITE));
}
}
LockModeType Options:
PESSIMISTIC_READ: ডেটা পড়ার জন্য লক।PESSIMISTIC_WRITE: ডেটা আপডেট বা ডিলিটের জন্য লক।PESSIMISTIC_FORCE_INCREMENT: লক সহ ভার্সন আপডেট।
উদাহরণ: Pessimistic Locking
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Transactional
public void updateProductWithLock(Long id, Double newPrice) {
Product product = productRepository.findProductWithPessimisticLock(id)
.orElseThrow(() -> new RuntimeException("Product not found"));
product.setPrice(newPrice);
}
}
Optimistic vs Pessimistic Locking
| বৈশিষ্ট্য | Optimistic Locking | Pessimistic Locking |
|---|---|---|
| ব্যবহার ক্ষেত্র | সংঘর্ষের সম্ভাবনা কম। | সংঘর্ষের সম্ভাবনা বেশি। |
| পারফরম্যান্স | লকিংয়ের জন্য অতিরিক্ত ওভারহেড নেই। | ডেটাবেস লকিং ওভারহেড বেশি। |
| কনফ্লিক্ট হ্যান্ডলিং | ডেটা সংঘর্ষ হলে Exception থ্রো করে। | ডেটা সংঘর্ষ হওয়ার আগে লক করে প্রতিরোধ করে। |
Hibernate-এ Locking কৌশল ব্যবহার করে ডেটার কনসিস্টেন্সি এবং সঠিকতা নিশ্চিত করা যায়। Optimistic Locking পারফরম্যান্সে উন্নত হলেও, Pessimistic Locking ডেটা নিরাপত্তা নিশ্চিত করে। সঠিক ব্যবহারের জন্য অ্যাপ্লিকেশন কনটেক্সট অনুযায়ী Locking কৌশল বেছে নিতে হবে।
Read more